// DDAutoDelete.h: interface 
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DDAutoDelete_H__INCLUDED_)
#define AFX_DDAutoDelete_H__INCLUDED_

#include "winsock2.h"

class DDCriticalSection
{
public:
	DDCriticalSection(){::InitializeCriticalSection(&m_sect);}
	~DDCriticalSection(){::DeleteCriticalSection(&m_sect);}

public:
    bool Lock(){ ::EnterCriticalSection(&m_sect); return true; }
	bool Unlock(){ ::LeaveCriticalSection(&m_sect); return true; }

private:
    CRITICAL_SECTION m_sect;
};

struct DD_AUTO_LOCK
{
	DD_AUTO_LOCK(DDCriticalSection* pLock)
	{
		m_pLock = pLock;
		if( NULL != m_pLock )
		{
			m_pLock->Lock();
		}
	}
	~DD_AUTO_LOCK()
	{
		if( NULL != m_pLock )
		{
			m_pLock->Unlock();
		}
	}
	void UnLock()
	{
		if( NULL != m_pLock )
		{
			m_pLock->Unlock();
		}
	}
	void ReLock()
	{
		if( NULL != m_pLock )
		{
			m_pLock->Lock();
		}
	}
	void CancelLock()
	{
		if( NULL != m_pLock )
		{
			m_pLock->Unlock();
			m_pLock = NULL;
		}
	}
	DDCriticalSection* m_pLock;
};

struct DD_AUTO_CLOSESOCKET
{
	DD_AUTO_CLOSESOCKET(SOCKET *pSocket)
	{
		m_pSocket = pSocket;
	}
	~DD_AUTO_CLOSESOCKET()
	{
		if( NULL != m_pSocket && NULL != *m_pSocket )
		{
			closesocket(*m_pSocket);
			*m_pSocket = NULL;
		}
	}
	SOCKET *m_pSocket;
};

struct DD_AUTO_WSACLOSEEVENT
{
	DD_AUTO_WSACLOSEEVENT(WSAEVENT *pEvent)
	{
		m_pEvent = pEvent;
	}
	~DD_AUTO_WSACLOSEEVENT()
	{
		if( NULL != m_pEvent && NULL != *m_pEvent )
		{
			WSACloseEvent(*m_pEvent);
			*m_pEvent = NULL;
		}
	}
	WSAEVENT *m_pEvent;
};

#endif // !defined(AFX_DDAutoDelete_H__INCLUDED_)
